package craky.keeper.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.List;
import java.util.PropertyResourceBundle;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.content.Context;
import android.content.res.Resources;
import android.os.Environment;
import android.widget.Toast;
import craky.keeper.server.KeeperService;
import craky.keeper.server.R;

public class Util
{
    private static final String KEEPER_SERVICE_CLASS_NAME = KeeperService.class.getName();

    public static final String MESSAGE_KEY = "KEEPER_MESSAGE";

    public static final String SERVICE_ACTION_RESULT_KEY = "SERVICE_ACTION_RESULT";

    public static String keeperDataParentPath;

    public static String keeperDataPath;

    public static enum ServiceActionResult
    {
        Start_OK, Stop_OK, Start_Exception, Stop_Exception, Copy_File_Error
    }

    public static boolean isKeeperServiceRunning(Activity activity)
    {
        ActivityManager manager = (ActivityManager)activity.getSystemService(Activity.ACTIVITY_SERVICE);
        List<RunningServiceInfo> services = manager.getRunningServices(Integer.MAX_VALUE);
        boolean running = false;

        for(RunningServiceInfo service: services)
        {
            if(KEEPER_SERVICE_CLASS_NAME.equals(service.service.getClassName()))
            {
                running = true;
                break;
            }
        }

        return running;
    }

    public static Boolean copyFiles(Context context)
    {
        Boolean result = null;
        File keeperDataRoot = new File(keeperDataPath);

        if(!keeperDataRoot.exists())
        {
            IOUtil.mkdirs(keeperDataRoot);
            int[] fileIds = {R.raw.category, R.raw.category_132e2d0d1bafb6354, R.raw.income, R.raw.income_132e2d1165f1f1235b, R.raw.pay,
                            R.raw.pay_132e2d0f68c9505f, R.raw.smallsql, R.raw.user, R.raw.user_132e2d0ae4c6b9c84};
            String[] fileNames = {"category.sdb", "category_132e2d0d1bafb6354.idx", "income.sdb", "income_132e2d1165f1f1235b.idx", "pay.sdb",
                            "pay_132e2d0f68c9505f.idx", "smallsql.master", "user.sdb", "user_132e2d0ae4c6b9c84.idx"};
            int fileCount = fileIds.length;
            String location = keeperDataRoot.getAbsolutePath();
            Resources resources = context.getResources();

            for(int i = 0; i < fileCount; i++)
            {
                try
                {
                    copyFile(resources.openRawResource(fileIds[i]), location + "/" + fileNames[i]);
                    result = true;
                }
                catch(Exception e)
                {
                    deleteDataFiles(keeperDataRoot);
                    result = false;
                    break;
                }
            }
        }

        return result;
    }

    private static void deleteDataFiles(File keeperDataRoot)
    {
        if(keeperDataRoot.exists())
        {
            File[] files = keeperDataRoot.listFiles();

            for(File file: files)
            {
                file.delete();
            }

            keeperDataRoot.delete();
        }
    }

    private static void copyFile(InputStream in, String path) throws IOException
    {
        IOUtil.copyFile(in, new File(path), true);
    }

    public static boolean hasExternalStorage()
    {
        return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
    }

    public static void showToast(Context context, CharSequence text)
    {
        Toast.makeText(context, text, Toast.LENGTH_LONG).show();
    }

    public static String getLocalhostIP()
    {
        String ip = null;

        try
        {
            Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces();
            NetworkInterface netInterface;
            InetAddress inetAddress;
            Enumeration<InetAddress> addresses;

            loopInterfaces: while(netInterfaces.hasMoreElements())
            {
                netInterface = netInterfaces.nextElement();

                if(netInterface.getName().toLowerCase().contains("usbnet"))
                {
                    continue;
                }

                addresses = netInterface.getInetAddresses();

                while(addresses.hasMoreElements())
                {
                    inetAddress = addresses.nextElement();

                    if(!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address)
                    {
                        ip = inetAddress.getHostAddress();
                        break loopInterfaces;
                    }
                }
            }
        }
        catch(Exception e)
        {}

        return ip;
    }

    public static int getCustomPort()
    {
        int port = 0;
        FileInputStream inputStream = null;

        try
        {
            inputStream = new FileInputStream(keeperDataParentPath + "/config.properties");
            PropertyResourceBundle resourceBundle = new PropertyResourceBundle(inputStream);
            port = Integer.parseInt(resourceBundle.getString("Server_Port"));
        }
        catch(Exception e)
        {
            port = 0;
        }
        finally
        {
            if(inputStream != null)
            {
                try
                {
                    inputStream.close();
                }
                catch(Exception e)
                {}
            }
        }

        return port;
    }
}